#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <ucontext.h>
#include "../../src/thread.h"

static void * exitThenJoin(void *arg)
{
  int * number = (int*)arg;
  printf("Thread %d - Argument %d: EXIT then JOIN\n",thread_self(),*number);
  thread_exit(arg);
}

static void * joinThenExit(void *arg)
{
  int * number = (int*)arg;

  printf("Thread %d - Argument %d: JOIN then EXIT\n",thread_self(),*number);
  thread_yield();
  printf("Thread %d - Argument %d: after 1st yield\n",thread_self(),*number);
  thread_yield();
  printf("Thread %d - Argument %d: FINISH after 2nd yield\n",thread_self(),*number);

  thread_exit(arg);
}

int main(void){
  thread_t th1, th2, th3, th4, th5, th6;
  void* retval1; void* retval2; void* retval3; 
  void* retval4; void* retval5; void* retval6;
  int arg1 = 1, arg2 = 2, arg3 = 3;
  int arg4 = 4, arg5 = 5, arg6 = 6;
  int err;

//lancer les thread
  printf("[LANCEMENT] \n");
  err = thread_create(&th1,exitThenJoin, &arg1);
  assert(!err);
  err = thread_create(&th2,exitThenJoin, &arg2);
  assert(!err);
  err = thread_create(&th3,exitThenJoin, &arg3);
  assert(!err);
  err = thread_create(&th4,joinThenExit, &arg4);
  assert(!err);
  err = thread_create(&th5,joinThenExit, &arg5);
  assert(!err);
  err = thread_create(&th6,joinThenExit, &arg6);
  assert(!err);
 
//attendre leurs terminaisons
  printf("\n[ATTENTE]\n");
  err = thread_join(th1,&retval1);
  assert(!err);
  err = thread_join(th4,&retval4);
  assert(!err);
  err = thread_join(th2,&retval2);
  assert(!err);
  err = thread_join(th5,&retval5);
  assert(!err);
  err = thread_join(th6,&retval6);
  assert(!err);
  err = thread_join(th3,&retval3);
  assert(!err);

//Afficher les valeurs de retour
  printf("Les valeurs de retour:\n");
  printf("       retval1 = %d\n", *((int*)retval1));
  printf("       retval2 = %d\n", *((int*)retval2));
  printf("       retval3 = %d\n", *((int*)retval3));
  printf("       retval4 = %d\n", *((int*)retval4));
  printf("       retval5 = %d\n", *((int*)retval5));
  printf("       retval6 = %d\n", *((int*)retval6));

  return EXIT_SUCCESS;
}
